# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is dual-licensed under either the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree or the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree. You may select, at your option, one of the
# above-listed licenses.

# pyre-strict


import json
import tempfile

from buck2.tests.e2e_util.api.buck import Buck
from buck2.tests.e2e_util.buck_workspace import buck_test
from buck2.tests.e2e_util.helper.golden import golden

# This file was generated by running:
#
# ```
# > buck2 build //:long_build --local-only --no-remote-cache
# > cp $(buck2 log path) buildlog.meta-only.pb.zst
# ```
#
# In the data directory. We check it in instead of re-generating it on every test to get
# deterministic timings
LOG_SOURCE = "buildlog.meta-only.pb.zst"


@buck_test()
async def test_whatup_command(buck: Buck) -> None:
    log = (await buck.log("show", LOG_SOURCE)).stdout.strip()
    log_file = tempfile.NamedTemporaryFile(
        suffix=".json-lines", mode="w+", delete=False
    )
    # Truncate log when analysis started
    with log_file as f:
        lines = log.splitlines()
        for line in lines:
            f.write(line + "\n")
            if "AnalysisStage" in line:
                break
        f.close()

    ext = await buck.log("whatup", log_file.name)
    golden(
        output=ext.stderr,
        rel_path="at_analysis_start.stderr.golden",
    )


@buck_test()
async def test_whatup_after_command(buck: Buck) -> None:
    # Get event log
    log = (await buck.log("show", LOG_SOURCE)).stdout.strip()
    elapsed = [0, 0]

    # Get first timestamp
    lines = log.splitlines()
    first_event = json.loads(lines[1])
    first_timestamp = first_event["Event"]["timestamp"]
    # Get timestamp where rule execution starts
    for line in lines:
        if "Execute" in line:
            event = json.loads(line)
            # Calculate elapsed seconds, we add 1 to give some padding in order to catch the open span
            elapsed[0] = (event["Event"]["timestamp"][0] - first_timestamp[0]) + 1
            # Calculate elapsed millliseconds
            elapsed[1] = (
                event["Event"]["timestamp"][1] - first_timestamp[1]
            ) // 1000000
            break

    # Verify rule execution appears when running whatup at that timestamp
    action_start = (elapsed[0] * 1000) + abs(elapsed[1])
    ext = await buck.log("whatup", LOG_SOURCE, "--after", str(action_start))
    golden(
        output=ext.stderr,
        rel_path="after_rule_execution.stderr.golden",
    )
